package com.question.Design;
/**
 * 命令生产工厂
 * @author xiaou
 *
 */

import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

import com.question.entity.User;
import com.question.utils.InputOutUtils;
import com.question.view.Configure;
import com.question.view.command.CommandList;
import com.question.view.command.ExitCommand;
import com.question.view.command.HelpCommand;
import com.question.view.command.ICommand;
import com.question.view.command.INoLoginCommand;
import com.question.view.command.LoginCommand;
import com.question.view.command.SignupCommand;
import com.question.view.command.play.AcceptCommand;
import com.question.view.command.play.AnswerCommand;
import com.question.view.command.play.AskCommand;
import com.question.view.command.play.CatAnswerCommand;
import com.question.view.command.play.CatQuestionCommand;
import com.question.view.command.play.InfoCommand;
import com.question.view.command.play.ListCommand;
import com.question.view.command.play.LogoutCommand;
import com.question.view.command.play.MyQuestionCommand;
import com.question.view.command.play.PlayerSuper;
import com.question.view.command.play.RankCommand;

public class CommandFactory {
	private Map<CommandList,Class<? extends ICommand>> factoryMap = new HashMap<>();
	private static CommandFactory commandFactory;
	
	public static CommandFactory getCommandFactory() {
		if(commandFactory == null) {
			return commandFactory = new CommandFactory();
		}
		return commandFactory;
	}
	
	private CommandFactory() {
		factoryMap.put(CommandList.HELP,HelpCommand.class);
		factoryMap.put(CommandList.SIGNUP, SignupCommand.class);
		factoryMap.put(CommandList.LOGIN, LoginCommand.class);
		factoryMap.put(CommandList.EXIT, ExitCommand.class);
		factoryMap.put(CommandList.LIST, ListCommand.class);
		factoryMap.put(CommandList.ANSWER, AnswerCommand.class);
		factoryMap.put(CommandList.ASK, AskCommand.class);
		factoryMap.put(CommandList.MYQUESTION, MyQuestionCommand.class);
		factoryMap.put(CommandList.CATANSWER, CatAnswerCommand.class);
		factoryMap.put(CommandList.ACCEPT, AcceptCommand.class);
		factoryMap.put(CommandList.INFO, InfoCommand.class);
		factoryMap.put(CommandList.RANK, RankCommand.class);
		factoryMap.put(CommandList.LOGOUT,LogoutCommand.class);
		factoryMap.put(CommandList.CATQUESTION,CatQuestionCommand.class);
	}
	public ICommand buildCommand(CommandList cmd, User user) {
		Class<? extends ICommand> clazz = factoryMap.get(cmd);
		if(clazz == null) {
			InputOutUtils.print("Failed to initialize proxy object");
			return null;
		}
		try {
			ICommand instance = (ICommand) clazz.newInstance();
			if(instance instanceof PlayerSuper) {
				PlayerSuper player  = (PlayerSuper) instance;
				player.setPlayer(user);
				return player;
			}else if(instance instanceof INoLoginCommand) {
				NotLoginProxy proxy = null;
				try {
					proxy = (NotLoginProxy) Class.forName(Configure.NOTLOGINPROXY).newInstance();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
				if(proxy == null) {
					InputOutUtils.print("Failed to initialize proxy object");
					System.exit(0);
				}
				proxy.setSubject(instance);
				INoLoginCommand NoLoginCommand = 
						(INoLoginCommand) Proxy.newProxyInstance(instance.getClass().getClassLoader(),
																 instance.getClass().getInterfaces(),proxy);
				return NoLoginCommand;
			}
			return instance;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}
}
